package ru.spb.osll.myfit.server;

import static ru.spb.osll.myfit.server.parser.PageParserUtils.getFullPath;

import java.io.IOException;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.TreeMap;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.client.service.FitService;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.common.TextParsingTools;
import ru.spb.osll.myfit.server.fixtureiterator.FileFactory;
import ru.spb.osll.myfit.server.handler.ContentHandler;
import ru.spb.osll.myfit.server.handler.PageLoader;
import ru.spb.osll.myfit.server.parser.PageParserUtils;
import ru.spb.osll.myfit.server.templateloader.JarTableTemplateLoader;
import ru.spb.osll.myfit.server.templateloader.TableTemplateLoader;
import ru.spb.osll.myfit.util.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 * 
 * @author kua
 */

@SuppressWarnings("serial")
public class FitServiceImpl extends RemoteServiceServlet implements FitService {
	private URLClassLoader m_classLoader;
	private TableTemplateLoader m_templateLoader;
	private TreeMap<String, String> m_templates;
	private ContentHandler m_contentHandler;
	private Map<String, Class<?>> m_fixtureClasses;
	private ImportsPrinter m_importsPrinter;
	private Configurator m_configurator;
	private Logger LOG = Logger.getLogger(FitServiceImpl.class);

	public FitServiceImpl() {
	 
	  LOG.info("FitServiceImpl constructor");
		m_configurator = Configurator.getInstance();
		m_classLoader = new MyFitClassLoaderFactory(new FileFactory())
				.createClassLoader(m_configurator.getJars(), m_configurator
						.getFixtures());
		m_templateLoader = new JarTableTemplateLoader(m_configurator.getFixtures(),
				m_classLoader);
		m_fixtureClasses = m_templateLoader.getFixtureClasses();
		m_templates = new TreeMap<String, String>(new FixtureNameComparator());
		for (Map.Entry<String, Class<?>> entry : m_fixtureClasses.entrySet()) {
			Class<?> clazz = entry.getValue();
			m_templates.put(StringUtils.splitCamelCase(clazz.getSimpleName()), entry.getKey());
		}

		m_importsPrinter = new ImportsPrinter(m_fixtureClasses, m_configurator);
		m_contentHandler = new ContentHandler(m_importsPrinter, m_configurator
				.getRoot(), new PageLoader(m_configurator
				.getRoot()));

	}

	@Override
	public Page loadPage(String path) {
		Page page = null;

		try {
			page = m_contentHandler.loadPage(getFullPath(m_configurator
					.getRoot(), path), path, null);

			for (PageElement element : page.getElements())
				if (element instanceof Table)
					setTableStyle((Table) element);

		} catch (IOException e) {
			e.printStackTrace();
		}
		LOG.info("load page: " + path);

		return page;
	}

	
  private void setTableStyle(Table table) {
    String name = table.getData().get(0).get(0).getText();
    Class<?> clazz = m_fixtureClasses.get(m_templates.get(name));
    table.setStyle(PageParserUtils.getTableStyle(clazz));
  }

	@Override
	public void savePage(String path, Page page) {
		try {
			LOG.debug("run savePage");
			m_contentHandler.savePage(getFullPath(m_configurator.getRoot(),
					path), page);
			LOG.info("save page: " + path);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public String getPagePath() {
	  LOG.debug("try get attrib \"pagePath\" ");
		String pagePath = (String) getServletContext().getAttribute(
				TextParsingTools.PAGE_PATH_ATTRIBUTE);
		LOG.debug("attrib \"pagePath\" = " + pagePath);
		getServletContext().removeAttribute(
				TextParsingTools.PAGE_PATH_ATTRIBUTE);

		return pagePath;
	}
}
